// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Queue.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   <see cref="IQueue{T}" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Diagnostics.CodeAnalysis;

namespace AzureContrib.WindowsAzure.StorageClient
{
	using Microsoft.WindowsAzure.StorageClient;

	/// <summary>
	/// Implementation of <see cref="IQueue{T}"/>.
	/// </summary>
	/// <typeparam name="T">The type of item you want to put in the queue.</typeparam>
	[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Justification = "This class is a generic queue. The naming is correct.")]
	public class Queue<T> : IQueue<T> where T : class
	{
		private ICloudQueue dataToValidateQueue;

		/// <summary>
		/// Initializes a new instance of the <see cref="Queue{T}"/> class. 
		/// </summary>
		/// <param name="cloudStorageAccountManager">
		/// The cloud Storage Account Manager.
		/// </param>
		/// <param name="context">
		/// The context.
		/// </param>
		/// <param name="queueName">
		/// The queue Name.
		/// </param>
		public Queue(ICloudStorageAccountManager cloudStorageAccountManager, string context, string queueName)
		{
			dataToValidateQueue = cloudStorageAccountManager.GetQueueReference(context, queueName);
		}

		/// <summary>
		/// <see cref="CloudQueue.AddMessage(Microsoft.WindowsAzure.StorageClient.CloudQueueMessage)"/> but we add a <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/> with a nice paylod <typeparamref name="T"/>.
		/// </summary>
		/// <param name="queueMessage">
		/// The queue Message to enqueue in the <see cref="Queue{T}"/>.
		/// </param>
		public void AddMessage(CloudQueueMessage<T> queueMessage)
		{
			dataToValidateQueue.AddMessage(queueMessage);
		}

		/// <summary>
		/// <see cref="CloudQueue.GetMessage()"/> as a <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/>
		/// </summary>
		/// <param name="visibilityTimeout">
		/// The visibility Timeout for the message on the queue.
		/// </param>
		/// <returns>
		/// The dequeued message of type <see cref="Microsoft.WindowsAzure.StorageClient.CloudQueueMessage"/>.
		/// </returns>
		public CloudQueueMessage<T> GetMessage(TimeSpan visibilityTimeout)
		{
			return dataToValidateQueue.GetMessage<T>(visibilityTimeout);
		}

		/// <summary>
		/// Delete a message from the queue.
		/// <seealso cref="IQueue{T}.DeleteMessage"/>
		/// </summary>
		/// <param name="toDelete">
		/// The actual message to Delete from the queue.
		/// </param>
		public void DeleteMessage(CloudQueueMessage<T> toDelete)
		{
			dataToValidateQueue.DeleteMessage(toDelete);
		}

		/// <summary>
		/// Check to see if there is a message on the queue. <seealso cref="IQueue{T}.HasMessage"/>
		/// </summary>
		/// <returns>True if there is a message in the queue.</returns>
		public bool HasMessage()
		{
			return dataToValidateQueue.PeekMessage() != null;
		}
	}
}